// 大文件 边读边写 控制速度


const fs = require('fs')
const path = require('path')
const EventEmitter = require('events');
class MyStream extends EventEmitter {
	constructor(stream, speed, fileName) {
		super()
		// 读取流
		this._stream = stream
		// 速度控制
		this._speed = speed
		this._readBytes = 0 //已读字节
		this._firstTimestamp = Date.now()//开始时间戳
		this.newFileName = fileName
		// 监控内存情况
		setInterval(() => {
			// this.printMemoryUsage()
		}, 1000);
		// 读取文件流
		stream.on('data', async (chunk) => {
			this._readBytes += chunk.length;
			// this._readBytesSecond += chunk.length;
			// 上报 readdata 事件
			try {
				fs.appendFileSync(this.newFileName, chunk, { encoding: 'utf8' })
				this.emit('readdata', chunk);
				this.checkSpeed()
			} catch (error) {
				throw error
			}

		});
		// 读取流结束
		stream.on('end', () => {
			// this._ended = true;
			this.emit('readend');
		});

	}
	// 停止读取文件
	pause() {
		this._paused = true
		this._stream.pause()
	}
	// 继续读取文件
	resume() {
		this._paused = false
		this._stream.resume()
	}
	// 间隔检查速度
	checkSpeed() {
		if (this.isTooFast()) {
			console.log('over speed');
			this.pause()
			// 添加定时器监控 当不超速时继续读流
			let tTimer = setInterval(() => {
				if (!this.isTooFast()) {
					clearInterval(tTimer)
					this.resume()
					console.log('go on read');
				}
			}, 100);
		} else {
			console.log('do not over speed');
		}
	}
	// 检查速度是否太快
	isTooFast() {
		let t = (Date.now() - this._firstTimestamp) / 1000
		let bps = this._readBytes / t
		return bps > this._speed
	}
	// 查看内存情况
	printMemoryUsage() {
		const info = process.memoryUsage();
		console.log('rss=%s, heapTotal=%s, heapUsed=%s', this._mb(info.rss), this._mb(info.heapTotal), this._mb(info.heapUsed));
	}
	// 换算MB
	_mb(v) {
		return (v / 1024 / 1024).toFixed(2) + 'MB';
	}

}
const stream = fs.createReadStream(path.join(__dirname, 'file/a.txt'), { encoding: 'utf8', highWaterMark: 1024 * 1024 * 1 })
// 要读取的文件流，速度值,copy路径
const myStream = new MyStream(stream, 10 * 1024 * 1024, path.join(__dirname, '/file/copy.txt'))
myStream.on('readdata', (data) => {
})
myStream.on("readend", () => {
	console.log('readend');
})

console.log(1);
